package cn.wolfcode.car.business.service.impl;

import cn.wolfcode.car.business.domain.BpmnInfo;
import cn.wolfcode.car.business.domain.CarPackageAudit;
import cn.wolfcode.car.business.domain.ServiceItem;
import cn.wolfcode.car.business.mapper.BpmnInfoMapper;
import cn.wolfcode.car.business.mapper.CarPackageAuditMapper;
import cn.wolfcode.car.business.mapper.ServiceItemMapper;
import cn.wolfcode.car.business.qo.ServiceItemQueryObject;
import cn.wolfcode.car.business.service.IServiceItemService;
import cn.wolfcode.car.common.base.page.TablePageInfo;
import cn.wolfcode.car.common.exception.BusinessException;
import cn.wolfcode.car.common.util.Convert;
import cn.wolfcode.car.shiro.ShiroUtils;
import com.github.pagehelper.PageHelper;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class ServiceItemServiceImpl implements IServiceItemService {

    @Autowired
    private ServiceItemMapper serviceItemMapper;
    @Autowired
    private BpmnInfoMapper bpmnInfoMapper;
    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private RepositoryService repositoryService;

    @Override
    public TablePageInfo<ServiceItem> query(ServiceItemQueryObject qo) {
        PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        return new TablePageInfo<ServiceItem>(serviceItemMapper.selectForList(qo));
    }


    @Override
    public void save(ServiceItem serviceItem) {
        ServiceItem newItem = new ServiceItem();
        newItem.setName(serviceItem.getName());
        newItem.setOriginalPrice(serviceItem.getOriginalPrice());
        newItem.setDiscountPrice(serviceItem.getDiscountPrice());
        newItem.setCarPackage(serviceItem.getCarPackage());
        newItem.setServiceCatalog(serviceItem.getServiceCatalog());
        newItem.setInfo(serviceItem.getInfo());
        newItem.setCreateTime(new Date());

        if (ServiceItem.CARPACKAGE_NO.equals(newItem.getCarPackage())) {
            newItem.setAuditStatus(ServiceItem.AUDITSTATUS_NO_REQUIRED);
        } else {
            newItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        }

        serviceItemMapper.insert(newItem);
    }

    @Override
    public ServiceItem get(Long id) {
        return serviceItemMapper.selectOne(id);
    }


    @Override
    public void update(ServiceItem serviceItem) {
        ServiceItem dbItem = this.get(serviceItem.getId());

        dbItem.setName(serviceItem.getName());
        dbItem.setOriginalPrice(serviceItem.getOriginalPrice());
        dbItem.setDiscountPrice(serviceItem.getDiscountPrice());
        dbItem.setServiceCatalog(serviceItem.getServiceCatalog());
        dbItem.setInfo(serviceItem.getInfo());

        if (ServiceItem.AUDITSTATUS_AUDITING.equals(dbItem.getAuditStatus())
                || ServiceItem.SALESTATUS_ON.equals(dbItem.getSaleStatus())) {
            throw new BusinessException("异常操作");
        }
        if (ServiceItem.CARPACKAGE_YES.equals(dbItem.getCarPackage())
                && ServiceItem.AUDITSTATUS_APPROVED.equals(dbItem.getAuditStatus())) {
            dbItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        }
        serviceItemMapper.update(dbItem);
    }

    @Override
    public void deleteBatch(String ids) {
        Long[] dictIds = Convert.toLongArray(ids);
        for (Long dictId : dictIds) {
            serviceItemMapper.delete(dictId);
        }
    }

    @Override
    public List<ServiceItem> list() {
        return serviceItemMapper.selectAll();
    }


    @Override
    public void saleOff(Long id) {
        ServiceItem serviceItem = this.get(id);
        if (ServiceItem.SALESTATUS_ON.equals(serviceItem.getSaleStatus())) {
            serviceItemMapper.changeSale(ServiceItem.SALESTATUS_OFF, id);
        } else {
            throw new BusinessException("异常操作");
        }

    }

    @Override
    public void saleOn(Long id) {
        ServiceItem serviceItem = this.get(id);
        if (ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())
                && !ServiceItem.AUDITSTATUS_APPROVED.equals(serviceItem.getAuditStatus())) {
            throw new BusinessException("异常操作");
        }
        serviceItemMapper.changeSale(ServiceItem.SALESTATUS_ON, id);
    }

    @Override
    public void startAudit(Long id, Long bpmnInfoId, Long director, Long finance, String info) {
        // 1.获得服务单项对象
        ServiceItem serviceItem = serviceItemMapper.selectOne(id);
        // 1.校验状态是否可发起审核 是套餐且审核状态不为 审核中 和 已通过
        if (ServiceItem.CARPACKAGE_NO.equals(serviceItem.getCarPackage())) {
            throw new BusinessException("非套餐无需审核");
        }
        if (ServiceItem.AUDITSTATUS_AUDITING.equals(serviceItem.getAuditStatus())
                ||ServiceItem.AUDITSTATUS_APPROVED.equals(serviceItem.getAuditStatus())) {
            throw new BusinessException("异常操作");
        }
        // 获得 bpmnInfo 列表对象
        BpmnInfo bpmnInfo = bpmnInfoMapper.selectOne(bpmnInfoId);
        // 获得流程定义对象,判断状态是否挂起
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
                processDefinitionId(bpmnInfo.getActProcessId()).
                singleResult();
        // processDefinition.isSuspended() 返回 boolean值,
        if (processDefinition.isSuspended()) {
            throw new BusinessException("套餐审核流程已挂起,暂无法申请");
        }
        // 3.创建 carPackageAudit 对象,封装数据并保存
        CarPackageAudit carPackageAudit = new CarPackageAudit();
        carPackageAudit.setServiceItemId(id);
        carPackageAudit.setServiceItemInfo(serviceItem.getInfo());
        carPackageAudit.setServiceItemPrice(serviceItem.getDiscountPrice());

        carPackageAudit.setCreator(ShiroUtils.getUser().getUserName());

        carPackageAudit.setBpmnInfoId(bpmnInfoId);
        carPackageAudit.setAuditorId(director);
        carPackageAudit.setCreateTime(new Date());
        carPackageAudit.setInfo(info);
        // 4.保存生成 id 值,用于启动流程实例的 businessKey
        carPackageAuditMapper.insert(carPackageAudit);
        //设置流程变量 -- 审核人
        Map<String, Object> map = new HashMap<>();
        map.put("director",director);
        if (finance != null) {
            map.put("finance",finance);
        }
        map.put("discountPrice",serviceItem.getDiscountPrice().longValue());
        // 5.启动流程实例,返回流程实例对象,设置 businessKey 和 流程变量
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(bpmnInfo.getActProcessKey(),
                carPackageAudit.getId() + "",
                            map);
        // 6.设置 流程实例 id
        carPackageAudit.setInstanceId(instance.getId());

        // 更新数据保存流程实例 id
        carPackageAuditMapper.updateInstanceId(Long.valueOf(instance.getId()),carPackageAudit.getId());

        // 7.发起审核成功,将服务单项审核窗台更改为 审核中
        serviceItemMapper.changeStatus(ServiceItem.AUDITSTATUS_AUDITING,id);


    }


}
